iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
AI & Data

「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰系列 第 9

【Day9】CNN卷積神經網絡 :基本概念到模型建構與訓練

  • 分享至 

  • xImage
  •  

昨天介紹完DNN而今天會講

  • CNN
    卷積層
    ----卷積核
    ----特徵圖
    ----步長
    ----填充
    池化層
    ----最大池化
    ----平均池化
  • 模型實作
    CNN相較DNN結構比較複雜,可能需要再多加操作幾次才會熟悉,下面讓我們開始吧!

CNN(卷積神經網絡)

卷積神經網絡(Convolutional Neural Network,CNN)大多用於處理和分析具有網格結構數據,如圖像和影片。CNN的獨特之處在於它使用卷積層(Convolutional Layers)池化層(Pooling Layers),來自動從輸入數據中學習特徵。
這種架構使得CNN在圖像分類、物體檢測、影像分割等機器視覺任務中表現出色。它的成功來自於能夠捕捉局部特徵、減少參數數量以及具有平移不變性。CNN廣泛應用於計算機視覺領域,改變了圖像處理和分析的方式,下面再讓我們說明卷積層與池化層。

卷積層(Convolutional Layers)

卷積層就像是一個過濾器,它在圖像上滑動,逐步檢測圖像的不同特徵,這些過濾器每次只處理圖像的一個小區域,並計算該區域的特徵。通過這樣的操作,卷積層可以捕捉到圖像中的局部特徵,並且具有平移不變性,意味著它能夠識別相同特徵的不同位置。

圖片來源:https://saturncloud.io/blog/a-comprehensive-guide-to-convolutional-neural-networks-the-eli5-way/

卷積核(Filter)

卷積層包含多個卷積核,每個卷積核都是一個小的矩陣,它負責捕捉圖像中的特定特徵,如邊緣、紋理等。通過在輸入圖像上滑動卷積核,可以計算出特徵圖。

特徵圖(Feature Map)

特徵圖是卷積操作的輸出,它是一個二維數組,包含了捕捉到的特徵信息。每個卷積核生成一個特徵圖,多個卷積核可以生成多個特徵圖。

步長(Stride):

步長是指卷積過程中卷積核(上圖移動的框框)在輸入數據上滑動的步伐(每次橫移格數)。它控制了卷積操作的輸出尺寸。較大的步長會導致輸出尺寸縮小,而較小的步長會保持較大的輸出尺寸。步長的選擇可以影響模型的特徵提取能力和計算效率。較小的步長可以提供更多的局部特徵信息,但計算代價較高。

填充(Padding)

填充是指在輸入數據的周圍添加額外的值(通常是0),以擴大輸入的尺寸,並控制卷積的輸出尺寸。

圖片來源:https://datahacker.rs/what-is-padding-cnn/

會看到與上面GIF圖不同,上方GIF便是沒有填充,輸出後的圖明顯少了一圈,因此填充通常用於控制特徵圖的大小,以便在不同層之間保持特徵圖的大小一致,這對於構建深度卷積神經網絡(CNN)模型很重要。

總之步長和填充是卷積操作中的重要參數,影響了模型的輸出尺寸和特徵提取能力,所以應根據具體的任務需求和模型架構進行調整,以達到最佳效果。

池化層(Pooling Layers)

池化層(Pooling Layers)是一種特徵圖壓縮技術,通過對每個區域進行統計操作(通常是最大池化或平均池化)來減小特徵圖的尺寸,這種操作通常在卷積層後,有助於減少計算複雜度提高模型的計算效率

最大池化(Max Pooling)

最大池化是最常見的池化操作之一。它在每個區域中選擇最大值作為代表,並將其用於新的特徵圖,有助於保留最重要的特徵,同時減小特徵圖的尺寸。

https://ithelp.ithome.com.tw/upload/images/20230924/201631841ObZVeObcO.png

平均池化(Average Pooling)

平均池化則是對每個區域中的值進行平均操作,而不是選擇最大值,這種池化方式也有助於減小特徵圖的尺寸,但可能會丟失一些細節信息。

https://ithelp.ithome.com.tw/upload/images/20230924/20163184WOiZboNwR7.png

以上就是關於CNN的說明
下面進入實作部分

模型實作

今天我們的訓練集一樣是來自MNIST,不過這次使用的是當中的Fashion以下是他GitHub的介紹

其主題是來自10其他種類共700個不同商品的正面圖片,大小、格式和訓練集/測試集劃分與原始的MNIST完全一致。60000/10000的訓練測試資料劃分,28x28的灰階圖。

  • 引入函式庫
import tensorflow as tf
from tensorflow.keras.datasets import fashion_mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout
from tensorflow.keras.callbacks import EarlyStopping
import matplotlib.pyplot as plt
  • 資料處理
# 載入 Fashion MNIST 數據集
(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()

# 數據預處理
x_train = x_train.reshape(-1, 28, 28, 1).astype('float32') / 255
x_test = x_test.reshape(-1, 28, 28, 1).astype('float32') / 255
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)
  • 建立模型
# 創建卷積神經網絡(CNN)模型
model = Sequential()
model.add(Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1))) # 卷積層 32特徵,卷積核3*3,激勵函數,輸入數據大小(28*28*1) 28*28圖 1為灰階(前面說過1大多黑白3為彩色)
model.add(MaxPooling2D(pool_size=(2, 2))) #池化 矩陣大小2*2
model.add(Conv2D(64, kernel_size=(3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2))) #池化 矩陣大小2*2
model.add(Flatten()) #攤平
model.add(Dense(128, activation='relu')) #全連接層
model.add(Dropout(0.5)) 
model.add(Dense(10, activation='softmax')) #全連接層

Conv2D(特徵數量, 卷積核3*3, 激勵函數,) Conv2D Keras中用於添加二維卷積層的函數

MaxPooling2D 二維最大池化
Dropout(輸出層隨機失活)是一種正則化技術,用於減少神經網絡的過度擬合。在每次訓練迭代中,Dropout會隨機將一部分神經元(通常是50%)暫時關閉,不參與前向和反向傳播,以阻止神經網絡對特定神經元的過度依賴。

  • 其他定義與設定
# 編譯模型
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

# 定義早停回調函數以監控驗證集的損失
early_stopping = EarlyStopping(monitor='val_loss', patience=5, verbose=1)

# 訓練模型並使用早停回調函數
history = model.fit(x_train, y_train, batch_size=64, epochs=30, validation_split=0.2, callbacks=[early_stopping])

# 在測試集上評估模型
test_loss, test_accuracy = model.evaluate(x_test, y_test)
print(f"測試集上的準確率:{test_accuracy}")

# 輸出最後一個驗證集的損失
val_loss = history.history['val_loss'][-1]
print(f"最後一個驗證集的損失:{val_loss}")

這裡使用到了keras的early_stopping,它的用處在於訓練模型過程,若在設定次數內,模型沒有再進步則停止訓練,可以避免過擬合。

  • 繪製Loss圖
# 建立 LOSS 圖表
#train loss
plt.plot(history.history['loss'])
#test loss
plt.plot(history.history['val_loss'])
#標題
plt.title('Model loss')
#y軸標籤
plt.ylabel('Loss')
#x軸標籤
plt.xlabel('Epoch')
#顯示折線的名稱
plt.legend(['Train', 'Test'], loc='upper left')
#顯示折線圖
plt.show()

https://ithelp.ithome.com.tw/upload/images/20230924/20163184QRHfUHUbST.png

可以看到模型大概在7~8次訓練是最好的,並且模型在沒有再進步後即停止訓練,雖然early_stopping不會讓模型得到最好結果,但是能讓模型不會更糟還能避免過擬合。

以上就是CNN的介紹,如同前面介紹過CNN再圖片、影片等領域有著不錯表現,但這不代表DNN就比較差,而是要在不同情況選擇最適合的模型,在自行練習時也可以嘗試更改當中參數,也有助於讓自己了解程式在幹嘛,明天讓我們從RNN介紹起!明天見~


上一篇
【Day8】以DNN辨識mnist數據集 更多更多還要更多!!
下一篇
【Day10】RNN循環神經網路
系列文
「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言